The Two Pillars of
Inference: Estimation & Testing
Think of these as answering two complementary questions about an
unknown population parameter (e.g., mean μ, proportion p, effect size
Δ).
# Create a simple visualization of the two pillars
pillars_data <- data.frame(
Pillar = c("Estimation", "Hypothesis Testing"),
Question = c("\n \"What is it likely to be?\"", "\"Is there evidence for \n a specific claim?\""),
Key_Product = c("Confidence Interval", "p-value"),
Color = c("#3498db", "#e74c3c"),
Height = c(1, 1)
)
ggplot(pillars_data, aes(x = Pillar, y = Height, fill = Pillar)) +
geom_col(width = 0.8) +
geom_text(aes(label = Question), vjust = 2, color = "white", size = 4.5, fontface = "bold") +
geom_text(aes(label = Key_Product), vjust = -0.5, color = "black", size = 4) +
scale_fill_manual(values = c("#3498db", "#e74c3c")) +
theme_minimal() +
theme(
legend.position = "none",
axis.title = element_blank(),
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(hjust = 0.5, size = 14)
) +
ylim(0, 1.5) +
labs(title = "The Two Pillars of Statistical Inference")

Pillar 1: Estimation
— “What is it likely to be?”
- Goal: Determine the plausible values for a
parameter.
- Key Product: An interval of
plausible values.
- Big-Picture Mindset: You are mapping the
uncertainty terrain. You’re not picking one number as
the “answer”; you’re defining a range where the truth likely
resides.
Pillar 2: Hypothesis
Testing — “Is there evidence for a specific claim?”
- Goal: Evaluate the strength of evidence
against a specific, default hypothesis.
- Key Product: A probability
(p-value) measuring compatibility between data and the null
hypothesis.
- Big-Picture Mindset: You are acting as a
skeptical jury. The default (null) is innocence (no
effect). The data must provide strong enough evidence to convict (reject
the null).
Major Types &
Real-World Use Cases
Confidence
Intervals
What it is: A range of values, calculated from
sample data, that is likely to contain the true population parameter a
certain percentage of the time (e.g., 95%).
Big-Picture Interpretation: “If we were to
repeat this study 100 times, about 95 of the resulting intervals would
contain the true parameter. This specific interval is one of those
attempts.”
set.seed(123)
# Simulate 20 confidence intervals
n_sim <- 20
n <- 30
true_mean <- 100
true_sd <- 15
ci_data <- data.frame(
sim = 1:n_sim,
mean = numeric(n_sim),
lower = numeric(n_sim),
upper = numeric(n_sim),
contains_true = logical(n_sim)
)
for (i in 1:n_sim) {
sample_data <- rnorm(n, mean = true_mean, sd = true_sd)
test_result <- t.test(sample_data, conf.level = 0.95)
ci_data$mean[i] <- mean(sample_data)
ci_data$lower[i] <- test_result$conf.int[1]
ci_data$upper[i] <- test_result$conf.int[2]
ci_data$contains_true[i] <- (ci_data$lower[i] <= true_mean) & (ci_data$upper[i] >= true_mean)
}
ggplot(ci_data, aes(x = sim)) +
geom_errorbar(aes(ymin = lower, ymax = upper, color = contains_true),
width = 0.3, size = 1) +
geom_point(aes(y = mean), size = 2) +
geom_hline(yintercept = true_mean, linetype = "dashed", color = "red", size = 1) +
scale_color_manual(values = c("TRUE" = "darkgreen", "FALSE" = "darkred"),
labels = c("TRUE" = "Contains true mean", "FALSE" = "Does not contain true mean")) +
labs(x = "Simulation Number", y = "Value",
title = "Simulation of 20 Confidence Intervals (95% level)",
color = "Contains True Mean?") +
theme_minimal() +
theme(legend.position = "bottom")
Use-Case Examples
Market Research: A survey finds 60% of a sample
favor a new product. The 95% CI for the population
proportion is [56%, 64%].
# Example calculation for market research
n <- 500 # sample size
p_hat <- 0.60 # sample proportion
margin_error <- 1.96 * sqrt(p_hat * (1 - p_hat) / n)
ci_lower <- p_hat - margin_error
ci_upper <- p_hat + margin_error
cat(sprintf("Market Research Example:\n"),
sprintf("Sample proportion: %.1f%%\n", p_hat * 100),
sprintf("95%% Confidence Interval: [%.1f%%, %.1f%%]\n",
ci_lower * 100, ci_upper * 100),
"\nInterpretation: We are 95%% confident that the true favorability\n",
"among all customers is between ", round(ci_lower * 100, 1),
"% and ", round(ci_upper * 100, 1), "%.", sep = "")
Market Research Example:
Sample proportion: 60.0%
95% Confidence Interval: [55.7%, 64.3%]
Interpretation: We are 95%% confident that the true favorability
among all customers is between 55.7% and 64.3%.
Interpretation: We are 95% confident that the true
favorability among all customers is between 56% and 64%. This gives
management a realistic range for planning.
- Medicine: A clinical trial finds a new drug reduces
systolic blood pressure by an average of 12 mmHg, with a 95% CI
of [8, 16] mmHg.
Interpretation: The true average effect for the population
is likely between 8 and 16 mmHg. The interval provides both an estimate
(12) and a measure of its precision.
Hypothesis Tests (The
Decision Framework)
What it is: A formal procedure to decide between
a null hypothesis (H₀)—often a statement of “no
difference” or “no effect”—and an alternative hypothesis
(H₁).
The Core Logic: Assume H₀ is true. Ask: “How
surprising/unlikely is our observed sample data under this assumption?”
This probability is the p-value. A very small p-value
suggests the data is incompatible with H₀.
Use-Case
Examples:
- Quality Control: A factory claims its bolts have a
mean strength of 1000 psi. An auditor samples a batch.
- H₀: μ = 1000 psi (process is on spec).
- H₁: μ < 1000 psi (process is faulty).
A very low p-value leads to rejecting H₀, triggering a
machine recalibration.
- A/B Testing (Digital): Does a new webpage layout
(B) have a higher click-through rate than the old one (A)?
- H₀: p_B - p_A = 0 (no difference).
- H₁: p_B - p_A > 0 (B is better).
A p-value < a threshold (e.g., 0.05) provides statistical evidence to
launch the new layout.
Regression Inference
(Modeling Relationships)
What it is: Extends estimation and testing to
the parameters of a model, most commonly examining the
relationship between variables.
Big-Picture Mindset: You are determining which
modeled relationships are meaningfully non-zero after
accounting for random noise.
# Simulate regression data with confidence bands
set.seed(456)
n <- 100
x <- rnorm(n, mean = 50, sd = 15)
true_slope <- 2.5
true_intercept <- 10
y <- true_intercept + true_slope * x + rnorm(n, sd = 20)
# Fit linear model
model <- lm(y ~ x)
# Create prediction data
new_x <- seq(min(x), max(x), length.out = 100)
pred <- predict(model, newdata = data.frame(x = new_x), interval = "confidence")
# Plot
par(mfrow = c(1, 2))
# Plot 1: Data with regression line and CI
plot(x, y, pch = 19, col = rgb(0, 0, 1, 0.5),
main = "Regression with Confidence Band",
xlab = "Predictor (X)", ylab = "Response (Y)")
lines(new_x, pred[, "fit"], col = "red", lwd = 2)
lines(new_x, pred[, "lwr"], col = "red", lty = 2)
lines(new_x, pred[, "upr"], col = "red", lty = 2)
# Plot 2: Coefficient estimate with CI
coef_est <- coef(model)[2]
coef_ci <- confint(model)[2,]
plot(1, coef_est, xlim = c(0.5, 1.5), ylim = c(coef_ci[1] - 0.5, coef_ci[2] + 0.5),
pch = 19, cex = 1.5, col = "blue", xaxt = "n", xlab = "",
ylab = "Slope Coefficient", main = "Coefficient Estimate with 95% CI",
cex.main = 0.9)
segments(1, coef_ci[1], 1, coef_ci[2], lwd = 2)
abline(h = 0, lty = 3, col = "gray")
text(1, coef_est + 0.3, sprintf("%.2f", coef_est), pos = 3)
Use-Case
Examples
- Economics: A regression models house price against
square footage, bedrooms, and location.
- Inference on the slope for square footage: A 95% CI
tells us the likely dollar increase in price per extra sq. ft. A
hypothesis test (p-value) tells us if we can confidently say the
relationship isn’t zero.
Example Regression Output:
=================================
Coefficient for Square Footage:
Estimate: $150.25 per sq. ft.
95% CI: [$142.10, $158.40]
p-value: < 0.001
Interpretation: Each additional square foot is associated with
an estimated $150 increase in price, and we are 95% confident
the true increase is between $142 and $158.
- Public Health: A logistic regression studies risk
factors for a disease. The inference on the odds ratio for
smoking (e.g., OR = 2.5 with CI [2.1, 3.0]) allows us to state:
Smoking is associated with 2.5 times the odds of disease, and we are
confident the true increase is at least 2.1-fold.
Bayesian Inference
(The Coherent Update)
What it is: A paradigm that combines
prior knowledge/belief (prior distribution) with
observed data (likelihood) to form an updated
posterior distribution for a parameter.
Big-Picture Mindset: You treat parameters as
probabilistic entities. You start with a prior (which can be objective
or subjective), observe data, and rationally update your beliefs. The
result is a full probability distribution for the parameter.
# Simulate Bayesian updating
set.seed(789)
x <- seq(0, 1, length.out = 100)
# Prior (moderately informed)
prior <- dbeta(x, 8, 8)
# Likelihood (data: 15 successes out of 20 trials)
a <- 15
b <- 5
likelihood <- dbeta(x, a, b)
# Posterior
posterior <- dbeta(x, 8 + a, 8 + b)
# Plot
plot_df <- data.frame(
x = rep(x, 3),
density = c(prior, likelihood, posterior),
distribution = rep(c("Prior", "Likelihood (Data)", "Posterior"), each = length(x))
)
bayes <- ggplot(plot_df, aes(x = x, y = density, color = distribution, linetype = distribution)) +
geom_line(size = 1.2) +
scale_color_manual(values = c("Prior" = "blue", "Likelihood (Data)" = "steelblue", "Posterior" = "red")) +
scale_linetype_manual(values = c("Prior" = "solid", "Likelihood (Data)" = "solid", "Posterior" = "solid")) +
labs(x = "Parameter (e.g., success probability)", y = "Density",
#title = "Bayesian Updating: Prior → Likelihood → Posterior",
color = "Distribution", linetype = "Distribution") +
theme(
plot.margin = margin(t = 40, r = 20, b = 20, l = 20, unit = "pt"),
plot.title = element_text(
margin = margin(t = 20, b = 0)), # Top and bottom margins
axis.title.x = element_text(margin = margin(t = 10)),
axis.title.y = element_text(margin = margin(r = 10))) +
theme_minimal()
ggplotly(bayes)
Use-Case
Examples:
Drug Development: Early trials provide a
prior on a drug’s efficacy. A larger Phase 3 trial
provides data. Bayesian inference
combines them to produce a posterior probability that
the drug exceeds a minimum effectiveness threshold—a direct, intuitive
statement for decision-makers.
Machine Learning/Spam Filtering: The filter has
a prior belief about the probability an email is spam.
It updates this belief based on the data (presence of
keywords like “free,” “winner”). The posterior
probability dictates the “spam/not spam”
classification.
Synthesis &
Cautions
Key Relationships and
Comparisons
Comparison of Statistical Inference Methods
| Confidence Intervals |
What is the plausible range? |
Interval estimate |
Long-run frequency of coverage |
| Hypothesis Tests |
Is there evidence against H₀? |
p-value, decision |
Probability of data if H₀ true |
| Regression Inference |
What is the relationship between variables? |
Parameter estimates with CIs |
Effect size with uncertainty |
| Bayesian Inference |
What should we believe given data and prior? |
Posterior distribution |
Degree of belief in parameter values |
- Estimation (CI) and Testing (p-values) are linked:
A 95% CI that excludes a null value (like 0)
corresponds to a hypothesis test rejecting H₀ at α=0.05.
# Demonstrate relationship between CI and hypothesis test
# Simulate data where CI excludes 0
set.seed(321)
sample_data <- rnorm(50, mean = 1.5, sd = 2)
# T-test
test_result <- t.test(sample_data, mu = 0)
ci <- test_result$conf.int
cat(" Demonstration: Relationship between CI and Hypothesis Test\n",
"==========================================================\n",
sprintf("\n Sample mean: %.3f\n", mean(sample_data)),
sprintf("95%% Confidence Interval: [%.3f, %.3f]\n", ci[1], ci[2]),
sprintf("p-value for H₀: μ = 0: %.4f\n", test_result$p.value),
sprintf("\n we %s the null hypothesis at α=0.05.\n",
ifelse(test_result$p.value < 0.05, "REJECT", "FAIL TO REJECT")))
Demonstration: Relationship between CI and Hypothesis Test
==========================================================
Sample mean: 1.659
95% Confidence Interval: [1.116, 2.202]
p-value for H₀: μ = 0: 0.0000
we REJECT the null hypothesis at α=0.05.
Statistical vs. Practical Significance: A test
can find a tiny, statistically significant effect (due
to huge sample size), but it may be practically
meaningless. Always look at the estimated effect size
and its CI.
Inference Requires Representative Data: Garbage
in, garbage out. Biased sampling invalidates any inference, no matter
how sophisticated.
Frequentist (CI/Tests) vs. Bayesian Mindset:
- Frequentist: Probability = long-run frequency.
Parameters are fixed, data is random.
- Bayesian: Probability = degree of belief.
Parameters are random, data is fixed.
Both are powerful tools; the choice often depends on the question,
field, and availability of prior information.
Key Takeaway
Statistical inference is the science of disciplined learning
from data in the face of uncertainty. It moves us from simply
describing our sample (“The average in our data was 10”) to making
generalizable statements with quantified uncertainty
(“We are 95% confident the population average is between 9 and 11”).
Mastering the big picture allows you to choose the right tool for the
question at hand, from estimating a market size, to testing a new
medical treatment, to updating a recommendation algorithm.
LS0tDQp0aXRsZTogIkFuIE92ZXJ2aWV3IG9mIFN0YXRpc3RpY2FsIEluZmVyZW5jZXMiDQphdXRob3I6ICJDaGVuZyBQZW5nIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIHRvY19mbG9hdDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2NfY29sbGFwc2VkOiB5ZXMNCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCiAgcGRmX2RvY3VtZW50OiANCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNA0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIGZpZ193aWR0aDogMw0KICAgIGZpZ19oZWlnaHQ6IDMNCiAgd29yZF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAga2VlcF9tZDogeWVzDQplZGl0b3Jfb3B0aW9uczogDQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KDQpgYGB7Y3NzLCBlY2hvID0gRkFMU0V9DQojVE9DOjpiZWZvcmUgew0KICBjb250ZW50OiAiVGFibGUgb2YgQ29udGVudHMiOw0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1zaXplOiAxLjJlbTsNCiAgZGlzcGxheTogYmxvY2s7DQogIGNvbG9yOiBuYXZ5Ow0KICBtYXJnaW4tYm90dG9tOiAxMHB4Ow0KfQ0KDQoNCmRpdiNUT0MgbGkgeyAgICAgLyogdGFibGUgb2YgY29udGVudCAgKi8NCiAgICBsaXN0LXN0eWxlOnVwcGVyLXJvbWFuOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCg0KaDEudGl0bGUgeyAgICAvKiBsZXZlbCAxIGhlYWRlciBvZiB0aXRsZSAgKi8NCiAgZm9udC1zaXplOiAyMnB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KfQ0KDQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE1cHg7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KICBmb250LWZhbWlseTogc3lzdGVtLXVpOw0KICBjb2xvcjogbmF2eTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KDQpoNC5kYXRlIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgZm9udC1mYW1pbHk6ICJHaWxsIFNhbnMiLCBzYW5zLXNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCg0KaDEgeyAvKiBIZWFkZXIgMSAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCmgyIHsgLyogSGVhZGVyIDIgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KaDMgeyAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTZweDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNHB4Ow0KICBmb250LXdlaWdodDogYm9sZDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQovKiBBZGQgZG90cyBhZnRlciBudW1iZXJlZCBoZWFkZXJzICovDQouaGVhZGVyLXNlY3Rpb24tbnVtYmVyOjphZnRlciB7DQogIGNvbnRlbnQ6ICIuIjsNCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KfQ0KYGBgDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInBhbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwYW5kZXIiKQ0KICAgbGlicmFyeShwYW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikNCiAgbGlicmFyeShnZ3Bsb3QyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCg0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZml0ZGlzdHJwbHVzIikpIHsNCiAgaW5zdGFsbC5wYWNrYWdlcygiZml0ZGlzdHJwbHVzIikNCiAgbGlicmFyeShmaXRkaXN0cnBsdXMpDQp9DQojIyBsaWJyYXJ5KGZpdGRpc3RycGx1cykNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgIyBpbmNsdWRlIGNvZGUgY2h1bmsgaW4gdGhlIG91dHB1dCBmaWxlDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgICMgc29tZXRpbWVzLCB5b3UgY29kZSBtYXkgcHJvZHVjZSB3YXJuaW5nIG1lc3NhZ2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHlvdSBjYW4gY2hvb3NlIHRvIGluY2x1ZGUgdGhlIHdhcm5pbmcgbWVzc2FnZXMgaW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgb3V0cHV0IGZpbGUuIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBUUlVFLCAgICAjIHlvdSBjYW4gYWxzbyBkZWNpZGUgd2hldGhlciB0byBpbmNsdWRlIHRoZSBvdXRwdXQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpbiB0aGUgb3V0cHV0IGZpbGUuDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFLA0KICAgICAgICAgICAgICAgICAgICAgIGNvbW1lbnQgPSBOQQ0KICAgICAgICAgICAgICAgICAgICAgICkgIA0KYGBgDQoNClwNCg0KIyBUaGUgQmlnIFBpY3R1cmUgb2YgU3RhdGlzdGljYWwgSW5mZXJlbmNlDQoNCiMjIENvcmUgUGhpbG9zb3BoaWNhbCBGb3VuZGF0aW9uDQoNCioqU3RhdGlzdGljYWwgSW5mZXJlbmNlOioqIFRoZSBwcm9jZXNzIG9mIHVzaW5nICoqc2FtcGxlIGRhdGEqKiB0byBkcmF3IGNvbmNsdXNpb25zIGFib3V0IGEgKipwb3B1bGF0aW9uKiogb3IgdW5kZXJseWluZyBwcm9jZXNzLCB3aGlsZSAqKnF1YW50aWZ5aW5nIHVuY2VydGFpbnR5KiouDQoNCioqVGhlIEZ1bmRhbWVudGFsIFBhcmFkb3g6KiogV2UgdXNlIHdoYXQgaXMga25vd24gKGRhdGEpIHRvIGxlYXJuIGFib3V0IHdoYXQgaXMgdW5rbm93biAocGFyYW1ldGVycy90cnV0aCksIGFjY2VwdGluZyB0aGF0IG91ciBjb25jbHVzaW9ucyBhcmUgcHJvYmFiaWxpc3RpYywgbm90IGNlcnRhaW4uDQoNCj4gKipBbmFsb2d5OioqIFlvdSB0YXN0ZSBhIHNwb29uZnVsIG9mIHNvdXAgKHNhbXBsZSkgdG8gaW5mZXIgaWYgdGhlIHdob2xlIHBvdCAocG9wdWxhdGlvbikgaXMgd2VsbC1zZWFzb25lZC4gSW5mZXJlbmNlIGlzIHRoZSBmb3JtYWwsIG1lYXN1cmFibGUgdmVyc2lvbiBvZiB0aGlzIGFjdC4NCg0KDQoNCiMgVGhlIFR3byBQaWxsYXJzIG9mIEluZmVyZW5jZTogRXN0aW1hdGlvbiAmIFRlc3RpbmcNCg0KVGhpbmsgb2YgdGhlc2UgYXMgYW5zd2VyaW5nIHR3byBjb21wbGVtZW50YXJ5IHF1ZXN0aW9ucyBhYm91dCBhbiB1bmtub3duIHBvcHVsYXRpb24gcGFyYW1ldGVyIChlLmcuLCBtZWFuIM68LCBwcm9wb3J0aW9uIHAsIGVmZmVjdCBzaXplIM6UKS4NCg0KYGBge3IgcGlsbGFycy1kaWFncmFtLCBmaWcuY2FwPSIiLCBvdXQud2lkdGg9IjgwJSJ9DQojIENyZWF0ZSBhIHNpbXBsZSB2aXN1YWxpemF0aW9uIG9mIHRoZSB0d28gcGlsbGFycw0KcGlsbGFyc19kYXRhIDwtIGRhdGEuZnJhbWUoDQogIFBpbGxhciA9IGMoIkVzdGltYXRpb24iLCAiSHlwb3RoZXNpcyBUZXN0aW5nIiksDQogIFF1ZXN0aW9uID0gYygiXG4gIFwiV2hhdCBpcyBpdCBsaWtlbHkgdG8gYmU/XCIiLCAiXCJJcyB0aGVyZSBldmlkZW5jZSBmb3IgXG4gYSBzcGVjaWZpYyBjbGFpbT9cIiIpLA0KICBLZXlfUHJvZHVjdCA9IGMoIkNvbmZpZGVuY2UgSW50ZXJ2YWwiLCAicC12YWx1ZSIpLA0KICBDb2xvciA9IGMoIiMzNDk4ZGIiLCAiI2U3NGMzYyIpLA0KICBIZWlnaHQgPSBjKDEsIDEpDQopDQoNCmdncGxvdChwaWxsYXJzX2RhdGEsIGFlcyh4ID0gUGlsbGFyLCB5ID0gSGVpZ2h0LCBmaWxsID0gUGlsbGFyKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDAuOCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gUXVlc3Rpb24pLCB2anVzdCA9IDIsIGNvbG9yID0gIndoaXRlIiwgc2l6ZSA9IDQuNSwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IEtleV9Qcm9kdWN0KSwgdmp1c3QgPSAtMC41LCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA0KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiMzNDk4ZGIiLCAiI2U3NGMzYyIpKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTQpDQogICkgKw0KICB5bGltKDAsIDEuNSkgKw0KICBsYWJzKHRpdGxlID0gIlRoZSBUd28gUGlsbGFycyBvZiBTdGF0aXN0aWNhbCBJbmZlcmVuY2UiKQ0KYGBgDQoNCiMjIFBpbGxhciAxOiBFc3RpbWF0aW9uIOKAlCAiV2hhdCBpcyBpdCBsaWtlbHkgdG8gYmU/Ig0KDQoqICoqR29hbDoqKiBEZXRlcm1pbmUgdGhlIHBsYXVzaWJsZSB2YWx1ZXMgZm9yIGEgcGFyYW1ldGVyLg0KKiAqKktleSBQcm9kdWN0OioqIEFuICoqaW50ZXJ2YWwqKiBvZiBwbGF1c2libGUgdmFsdWVzLg0KKiAqKkJpZy1QaWN0dXJlIE1pbmRzZXQ6KiogWW91IGFyZSBtYXBwaW5nIHRoZSAqKnVuY2VydGFpbnR5IHRlcnJhaW4qKi4gWW91J3JlIG5vdCBwaWNraW5nIG9uZSBudW1iZXIgYXMgdGhlICJhbnN3ZXIiOyB5b3UncmUgZGVmaW5pbmcgYSByYW5nZSB3aGVyZSB0aGUgdHJ1dGggbGlrZWx5IHJlc2lkZXMuDQoNCg0KIyMgUGlsbGFyIDI6IEh5cG90aGVzaXMgVGVzdGluZyDigJQgIklzIHRoZXJlIGV2aWRlbmNlIGZvciBhIHNwZWNpZmljIGNsYWltPyINCg0KKiAqKkdvYWw6KiogRXZhbHVhdGUgdGhlIHN0cmVuZ3RoIG9mIGV2aWRlbmNlICphZ2FpbnN0KiBhIHNwZWNpZmljLCBkZWZhdWx0IGh5cG90aGVzaXMuDQoqICoqS2V5IFByb2R1Y3Q6KiogQSAqKnByb2JhYmlsaXR5IChwLXZhbHVlKSoqIG1lYXN1cmluZyBjb21wYXRpYmlsaXR5IGJldHdlZW4gZGF0YSBhbmQgdGhlIG51bGwgaHlwb3RoZXNpcy4NCiogKipCaWctUGljdHVyZSBNaW5kc2V0OioqIFlvdSBhcmUgYWN0aW5nIGFzIGEgKipza2VwdGljYWwganVyeSoqLiBUaGUgZGVmYXVsdCAobnVsbCkgaXMgaW5ub2NlbmNlIChubyBlZmZlY3QpLiBUaGUgZGF0YSBtdXN0IHByb3ZpZGUgc3Ryb25nIGVub3VnaCBldmlkZW5jZSB0byBjb252aWN0IChyZWplY3QgdGhlIG51bGwpLg0KDQoNCiMgTWFqb3IgVHlwZXMgJiBSZWFsLVdvcmxkIFVzZSBDYXNlcw0KDQojIyBDb25maWRlbmNlIEludGVydmFscyANCg0KKiAqKldoYXQgaXQgaXM6KiogQSByYW5nZSBvZiB2YWx1ZXMsIGNhbGN1bGF0ZWQgZnJvbSBzYW1wbGUgZGF0YSwgdGhhdCBpcyBsaWtlbHkgdG8gY29udGFpbiB0aGUgdHJ1ZSBwb3B1bGF0aW9uIHBhcmFtZXRlciBhIGNlcnRhaW4gcGVyY2VudGFnZSBvZiB0aGUgdGltZSAoZS5nLiwgOTUlKS4NCg0KKiAqKkJpZy1QaWN0dXJlIEludGVycHJldGF0aW9uOioqICJJZiB3ZSB3ZXJlIHRvIHJlcGVhdCB0aGlzIHN0dWR5IDEwMCB0aW1lcywgYWJvdXQgOTUgb2YgdGhlIHJlc3VsdGluZyBpbnRlcnZhbHMgd291bGQgY29udGFpbiB0aGUgdHJ1ZSBwYXJhbWV0ZXIuIFRoaXMgc3BlY2lmaWMgaW50ZXJ2YWwgaXMgb25lIG9mIHRob3NlIGF0dGVtcHRzLiINCg0KYGBge3IgY29uZmlkZW5jZS1pbnRlcnZhbC1kZW1vLCBmaWcuY2FwPSJWaXN1YWxpemluZyBDb25maWRlbmNlIEludGVydmFsczogOTUlIG9mIGludGVydmFscyBjb250YWluIHRoZSB0cnVlIHBhcmFtZXRlciAoZGFzaGVkIGxpbmUpIn0NCnNldC5zZWVkKDEyMykNCiMgU2ltdWxhdGUgMjAgY29uZmlkZW5jZSBpbnRlcnZhbHMNCm5fc2ltIDwtIDIwDQpuIDwtIDMwDQp0cnVlX21lYW4gPC0gMTAwDQp0cnVlX3NkIDwtIDE1DQoNCmNpX2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgc2ltID0gMTpuX3NpbSwNCiAgbWVhbiA9IG51bWVyaWMobl9zaW0pLA0KICBsb3dlciA9IG51bWVyaWMobl9zaW0pLA0KICB1cHBlciA9IG51bWVyaWMobl9zaW0pLA0KICBjb250YWluc190cnVlID0gbG9naWNhbChuX3NpbSkNCikNCg0KZm9yIChpIGluIDE6bl9zaW0pIHsNCiAgc2FtcGxlX2RhdGEgPC0gcm5vcm0obiwgbWVhbiA9IHRydWVfbWVhbiwgc2QgPSB0cnVlX3NkKQ0KICB0ZXN0X3Jlc3VsdCA8LSB0LnRlc3Qoc2FtcGxlX2RhdGEsIGNvbmYubGV2ZWwgPSAwLjk1KQ0KICBjaV9kYXRhJG1lYW5baV0gPC0gbWVhbihzYW1wbGVfZGF0YSkNCiAgY2lfZGF0YSRsb3dlcltpXSA8LSB0ZXN0X3Jlc3VsdCRjb25mLmludFsxXQ0KICBjaV9kYXRhJHVwcGVyW2ldIDwtIHRlc3RfcmVzdWx0JGNvbmYuaW50WzJdDQogIGNpX2RhdGEkY29udGFpbnNfdHJ1ZVtpXSA8LSAoY2lfZGF0YSRsb3dlcltpXSA8PSB0cnVlX21lYW4pICYgKGNpX2RhdGEkdXBwZXJbaV0gPj0gdHJ1ZV9tZWFuKQ0KfQ0KDQpnZ3Bsb3QoY2lfZGF0YSwgYWVzKHggPSBzaW0pKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBsb3dlciwgeW1heCA9IHVwcGVyLCBjb2xvciA9IGNvbnRhaW5zX3RydWUpLCANCiAgICAgICAgICAgICAgICB3aWR0aCA9IDAuMywgc2l6ZSA9IDEpICsNCiAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW4pLCBzaXplID0gMikgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSB0cnVlX21lYW4sIGxpbmV0eXBlID0gImRhc2hlZCIsIGNvbG9yID0gInJlZCIsIHNpemUgPSAxKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJUUlVFIiA9ICJkYXJrZ3JlZW4iLCAiRkFMU0UiID0gImRhcmtyZWQiKSwNCiAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlRSVUUiID0gIkNvbnRhaW5zIHRydWUgbWVhbiIsICJGQUxTRSIgPSAiRG9lcyBub3QgY29udGFpbiB0cnVlIG1lYW4iKSkgKw0KICBsYWJzKHggPSAiU2ltdWxhdGlvbiBOdW1iZXIiLCB5ID0gIlZhbHVlIiwgDQogICAgICAgdGl0bGUgPSAiU2ltdWxhdGlvbiBvZiAyMCBDb25maWRlbmNlIEludGVydmFscyAoOTUlIGxldmVsKSIsDQogICAgICAgY29sb3IgPSAiQ29udGFpbnMgVHJ1ZSBNZWFuPyIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpDQpgYGANCg0KKipVc2UtQ2FzZSBFeGFtcGxlcyoqDQoNCjEuICAqKk1hcmtldCBSZXNlYXJjaDoqKiBBIHN1cnZleSBmaW5kcyA2MCUgb2YgYSBzYW1wbGUgZmF2b3IgYSBuZXcgcHJvZHVjdC4gVGhlICoqOTUlIENJIGZvciB0aGUgcG9wdWxhdGlvbiBwcm9wb3J0aW9uKiogaXMgWzU2JSwgNjQlXS4gDQogICAgDQogICAgYGBge3IgbWFya2V0LXJlc2VhcmNoLWV4YW1wbGV9DQogICAgIyBFeGFtcGxlIGNhbGN1bGF0aW9uIGZvciBtYXJrZXQgcmVzZWFyY2gNCiAgICBuIDwtIDUwMCAgIyBzYW1wbGUgc2l6ZQ0KICAgIHBfaGF0IDwtIDAuNjAgICMgc2FtcGxlIHByb3BvcnRpb24NCiAgICBtYXJnaW5fZXJyb3IgPC0gMS45NiAqIHNxcnQocF9oYXQgKiAoMSAtIHBfaGF0KSAvIG4pDQogICAgY2lfbG93ZXIgPC0gcF9oYXQgLSBtYXJnaW5fZXJyb3INCiAgICBjaV91cHBlciA8LSBwX2hhdCArIG1hcmdpbl9lcnJvcg0KICAgIA0KICAgIGNhdChzcHJpbnRmKCJNYXJrZXQgUmVzZWFyY2ggRXhhbXBsZTpcbiIpLA0KICAgIHNwcmludGYoIlNhbXBsZSBwcm9wb3J0aW9uOiAlLjFmJSVcbiIsIHBfaGF0ICogMTAwKSwNCiAgICAgc3ByaW50ZigiOTUlJSBDb25maWRlbmNlIEludGVydmFsOiBbJS4xZiUlLCAlLjFmJSVdXG4iLCANCiAgICAgICAgICAgICAgICBjaV9sb3dlciAqIDEwMCwgY2lfdXBwZXIgKiAxMDApLA0KICAgICAiXG5JbnRlcnByZXRhdGlvbjogV2UgYXJlIDk1JSUgY29uZmlkZW50IHRoYXQgdGhlIHRydWUgZmF2b3JhYmlsaXR5XG4iLA0KICAgICAiYW1vbmcgYWxsIGN1c3RvbWVycyBpcyBiZXR3ZWVuICIsIHJvdW5kKGNpX2xvd2VyICogMTAwLCAxKSwgDQogICAgICAgICIlIGFuZCAiLCByb3VuZChjaV91cHBlciAqIDEwMCwgMSksICIlLiIsIHNlcCA9ICIiKQ0KICAgIGBgYA0KICAgIA0KKkludGVycHJldGF0aW9uOiogV2UgYXJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgdHJ1ZSBmYXZvcmFiaWxpdHkgYW1vbmcgYWxsIGN1c3RvbWVycyBpcyBiZXR3ZWVuIDU2JSBhbmQgNjQlLiBUaGlzIGdpdmVzIG1hbmFnZW1lbnQgYSByZWFsaXN0aWMgcmFuZ2UgZm9yIHBsYW5uaW5nLg0KDQoyLiAqKk1lZGljaW5lOioqIEEgY2xpbmljYWwgdHJpYWwgZmluZHMgYSBuZXcgZHJ1ZyByZWR1Y2VzIHN5c3RvbGljIGJsb29kIHByZXNzdXJlIGJ5IGFuIGF2ZXJhZ2Ugb2YgMTIgbW1IZywgd2l0aCBhICoqOTUlIENJIG9mIFs4LCAxNl0gbW1IZyoqLiANCg0KKkludGVycHJldGF0aW9uOiogVGhlIHRydWUgYXZlcmFnZSBlZmZlY3QgZm9yIHRoZSBwb3B1bGF0aW9uIGlzIGxpa2VseSBiZXR3ZWVuIDggYW5kIDE2IG1tSGcuIFRoZSBpbnRlcnZhbCBwcm92aWRlcyBib3RoIGFuIGVzdGltYXRlICgxMikgYW5kIGEgbWVhc3VyZSBvZiBpdHMgcHJlY2lzaW9uLg0KDQojIyBIeXBvdGhlc2lzIFRlc3RzIChUaGUgRGVjaXNpb24gRnJhbWV3b3JrKQ0KDQoqICoqV2hhdCBpdCBpczoqKiBBIGZvcm1hbCBwcm9jZWR1cmUgdG8gZGVjaWRlIGJldHdlZW4gYSAqKm51bGwgaHlwb3RoZXNpcyAoSOKCgCkqKuKAlG9mdGVuIGEgc3RhdGVtZW50IG9mICJubyBkaWZmZXJlbmNlIiBvciAibm8gZWZmZWN0IuKAlGFuZCBhbiAqKmFsdGVybmF0aXZlIGh5cG90aGVzaXMgKEjigoEpKiouDQoNCiogKipUaGUgQ29yZSBMb2dpYzoqKiBBc3N1bWUgSOKCgCBpcyB0cnVlLiBBc2s6ICJIb3cgc3VycHJpc2luZy91bmxpa2VseSBpcyBvdXIgb2JzZXJ2ZWQgc2FtcGxlIGRhdGEgdW5kZXIgdGhpcyBhc3N1bXB0aW9uPyIgVGhpcyBwcm9iYWJpbGl0eSBpcyB0aGUgKipwLXZhbHVlKiouIEEgdmVyeSBzbWFsbCBwLXZhbHVlIHN1Z2dlc3RzIHRoZSBkYXRhIGlzIGluY29tcGF0aWJsZSB3aXRoIEjigoAuDQoNCiMjIyAqKlVzZS1DYXNlIEV4YW1wbGVzOioqDQoNCjEuICAqKlF1YWxpdHkgQ29udHJvbDoqKiBBIGZhY3RvcnkgY2xhaW1zIGl0cyBib2x0cyBoYXZlIGEgbWVhbiBzdHJlbmd0aCBvZiAxMDAwIHBzaS4gQW4gYXVkaXRvciBzYW1wbGVzIGEgYmF0Y2guICANCiAgICAqICAgKipI4oKAOioqIM68ID0gMTAwMCBwc2kgKHByb2Nlc3MgaXMgb24gc3BlYykuICANCiAgICAqICAgKipI4oKBOioqIM68IDwgMTAwMCBwc2kgKHByb2Nlc3MgaXMgZmF1bHR5KS4gIA0KICAgIEEgdmVyeSBsb3cgcC12YWx1ZSBsZWFkcyB0byAqKnJlamVjdGluZyBI4oKAKiosIHRyaWdnZXJpbmcgYSBtYWNoaW5lIHJlY2FsaWJyYXRpb24uDQoNCjIuICAqKkEvQiBUZXN0aW5nIChEaWdpdGFsKToqKiBEb2VzIGEgbmV3IHdlYnBhZ2UgbGF5b3V0IChCKSBoYXZlIGEgaGlnaGVyIGNsaWNrLXRocm91Z2ggcmF0ZSB0aGFuIHRoZSBvbGQgb25lIChBKT8gIA0KICAgICogICAqKkjigoA6KiogcF9CIC0gcF9BID0gMCAobm8gZGlmZmVyZW5jZSkuICANCiAgICAqICAgKipI4oKBOioqIHBfQiAtIHBfQSA+IDAgKEIgaXMgYmV0dGVyKS4gIA0KICAgIEEgcC12YWx1ZSA8IGEgdGhyZXNob2xkIChlLmcuLCAwLjA1KSBwcm92aWRlcyBzdGF0aXN0aWNhbCBldmlkZW5jZSB0byAqKmxhdW5jaCB0aGUgbmV3IGxheW91dCoqLg0KDQpgYGB7ciBoeXBvdGhlc2lzLXRlc3QtZmxvdywgZmlnLmNhcD0iSHlwb3RoZXNpcyBUZXN0aW5nIERlY2lzaW9uIEZsb3ciLCBlY2hvPUZBTFNFfQ0KIyBDcmVhdGUgYSBmbG93Y2hhcnQtbGlrZSB2aXN1YWxpemF0aW9uDQpmbG93X2RhdGEgPC0gZGF0YS5mcmFtZSgNCiAgc3RlcCA9IGMoIjEuIFN0YXRlIEh5cG90aGVzZXMiLCANCiAgICAgICAgICAgIjIuIENvbGxlY3QgRGF0YSIsIA0KICAgICAgICAgICAiMy4gQ2FsY3VsYXRlIFN0YXRpc3RpYyIsIA0KICAgICAgICAgICAiNC4gQ29tcHV0ZSBwLXZhbHVlIiwNCiAgICAgICAgICAgIjUuIE1ha2UgRGVjaXNpb24iKSwNCiAgeCA9IDE6NSwNCiAgeSA9IHJlcCgxLCA1KQ0KKQ0KDQpnZ3Bsb3QoZmxvd19kYXRhLCBhZXMoeCA9IHgsIHkgPSB5KSkgKw0KICBnZW9tX3BvaW50KHNpemUgPSA0MCwgY29sb3IgPSAiIzJjM2U1MCIsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzdGVwKSwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gMykgKw0KICBnZW9tX3NlZ21lbnQoYWVzKHggPSB4Ky40NSwgeGVuZCA9IHggKyAuNTYsIHkgPSB5LCB5ZW5kID0geSksIA0KICAgICAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMSwgImNtIikpLCANCiAgICAgICAgICAgICAgIGNvbG9yID0gImRhcmtyZWQiLCBzaXplID0gMSkgKw0KICB4bGltKDAuNSwgNS41KSArDQogIHlsaW0oMC44LCAxLjIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicyh0aXRsZSA9ICJIeXBvdGhlc2lzIFRlc3RpbmcgUHJvY2VzcyBGbG93IikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41LCBzaXplID0gMTQpKQ0KYGBgDQoNCiMjIFJlZ3Jlc3Npb24gSW5mZXJlbmNlIChNb2RlbGluZyBSZWxhdGlvbnNoaXBzKQ0KDQoqICoqV2hhdCBpdCBpczoqKiBFeHRlbmRzIGVzdGltYXRpb24gYW5kIHRlc3RpbmcgdG8gdGhlIHBhcmFtZXRlcnMgb2YgYSAqKm1vZGVsKiosIG1vc3QgY29tbW9ubHkgZXhhbWluaW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB2YXJpYWJsZXMuDQoNCiogKipCaWctUGljdHVyZSBNaW5kc2V0OioqIFlvdSBhcmUgZGV0ZXJtaW5pbmcgd2hpY2ggbW9kZWxlZCByZWxhdGlvbnNoaXBzIGFyZSAqKm1lYW5pbmdmdWxseSBub24temVybyoqIGFmdGVyIGFjY291bnRpbmcgZm9yIHJhbmRvbSBub2lzZS4NCg0KYGBge3IgcmVncmVzc2lvbi1leGFtcGxlLCBmaWcuY2FwPSJSZWdyZXNzaW9uIEluZmVyZW5jZTogRXN0aW1hdGluZyByZWxhdGlvbnNoaXBzIHdpdGggdW5jZXJ0YWludHkiLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KIyBTaW11bGF0ZSByZWdyZXNzaW9uIGRhdGEgd2l0aCBjb25maWRlbmNlIGJhbmRzDQpzZXQuc2VlZCg0NTYpDQpuIDwtIDEwMA0KeCA8LSBybm9ybShuLCBtZWFuID0gNTAsIHNkID0gMTUpDQp0cnVlX3Nsb3BlIDwtIDIuNQ0KdHJ1ZV9pbnRlcmNlcHQgPC0gMTANCnkgPC0gdHJ1ZV9pbnRlcmNlcHQgKyB0cnVlX3Nsb3BlICogeCArIHJub3JtKG4sIHNkID0gMjApDQoNCiMgRml0IGxpbmVhciBtb2RlbA0KbW9kZWwgPC0gbG0oeSB+IHgpDQoNCiMgQ3JlYXRlIHByZWRpY3Rpb24gZGF0YQ0KbmV3X3ggPC0gc2VxKG1pbih4KSwgbWF4KHgpLCBsZW5ndGgub3V0ID0gMTAwKQ0KcHJlZCA8LSBwcmVkaWN0KG1vZGVsLCBuZXdkYXRhID0gZGF0YS5mcmFtZSh4ID0gbmV3X3gpLCBpbnRlcnZhbCA9ICJjb25maWRlbmNlIikNCg0KIyBQbG90DQpwYXIobWZyb3cgPSBjKDEsIDIpKQ0KIyBQbG90IDE6IERhdGEgd2l0aCByZWdyZXNzaW9uIGxpbmUgYW5kIENJDQpwbG90KHgsIHksIHBjaCA9IDE5LCBjb2wgPSByZ2IoMCwgMCwgMSwgMC41KSwgDQogICAgIG1haW4gPSAiUmVncmVzc2lvbiB3aXRoIENvbmZpZGVuY2UgQmFuZCIsDQogICAgIHhsYWIgPSAiUHJlZGljdG9yIChYKSIsIHlsYWIgPSAiUmVzcG9uc2UgKFkpIikNCmxpbmVzKG5ld194LCBwcmVkWywgImZpdCJdLCBjb2wgPSAicmVkIiwgbHdkID0gMikNCmxpbmVzKG5ld194LCBwcmVkWywgImx3ciJdLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCmxpbmVzKG5ld194LCBwcmVkWywgInVwciJdLCBjb2wgPSAicmVkIiwgbHR5ID0gMikNCg0KIyBQbG90IDI6IENvZWZmaWNpZW50IGVzdGltYXRlIHdpdGggQ0kNCmNvZWZfZXN0IDwtIGNvZWYobW9kZWwpWzJdDQpjb2VmX2NpIDwtIGNvbmZpbnQobW9kZWwpWzIsXQ0KDQpwbG90KDEsIGNvZWZfZXN0LCB4bGltID0gYygwLjUsIDEuNSksIHlsaW0gPSBjKGNvZWZfY2lbMV0gLSAwLjUsIGNvZWZfY2lbMl0gKyAwLjUpLA0KICAgICBwY2ggPSAxOSwgY2V4ID0gMS41LCBjb2wgPSAiYmx1ZSIsIHhheHQgPSAibiIsIHhsYWIgPSAiIiwNCiAgICAgeWxhYiA9ICJTbG9wZSBDb2VmZmljaWVudCIsIG1haW4gPSAiQ29lZmZpY2llbnQgRXN0aW1hdGUgd2l0aCA5NSUgQ0kiLA0KICAgICBjZXgubWFpbiA9IDAuOSkNCnNlZ21lbnRzKDEsIGNvZWZfY2lbMV0sIDEsIGNvZWZfY2lbMl0sIGx3ZCA9IDIpDQphYmxpbmUoaCA9IDAsIGx0eSA9IDMsIGNvbCA9ICJncmF5IikNCnRleHQoMSwgY29lZl9lc3QgKyAwLjMsIHNwcmludGYoIiUuMmYiLCBjb2VmX2VzdCksIHBvcyA9IDMpDQpgYGANCg0KIyMgVXNlLUNhc2UgRXhhbXBsZXMNCg0KMS4gICoqRWNvbm9taWNzOioqIEEgcmVncmVzc2lvbiBtb2RlbHMgaG91c2UgcHJpY2UgYWdhaW5zdCBzcXVhcmUgZm9vdGFnZSwgYmVkcm9vbXMsIGFuZCBsb2NhdGlvbi4gIA0KICAgICogICAqKkluZmVyZW5jZSBvbiB0aGUgc2xvcGUgZm9yIHNxdWFyZSBmb290YWdlOioqIEEgOTUlIENJIHRlbGxzIHVzIHRoZSBsaWtlbHkgZG9sbGFyIGluY3JlYXNlIGluIHByaWNlIHBlciBleHRyYSBzcS4gZnQuIEEgaHlwb3RoZXNpcyB0ZXN0IChwLXZhbHVlKSB0ZWxscyB1cyBpZiB3ZSBjYW4gY29uZmlkZW50bHkgc2F5IHRoZSByZWxhdGlvbnNoaXAgaXNuJ3QgemVyby4NCg0KYGBge3IgcmVncmVzc2lvbi1vdXRwdXQtZXhhbXBsZSwgZWNobz1GQUxTRX0NCiMgRGlzcGxheSBzYW1wbGUgcmVncmVzc2lvbiBvdXRwdXQNCmNhdCgiRXhhbXBsZSBSZWdyZXNzaW9uIE91dHB1dDpcbiIsDQogIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIiwNCiAiQ29lZmZpY2llbnQgZm9yIFNxdWFyZSBGb290YWdlOlxuIiwNCiAiICBFc3RpbWF0ZTogICQxNTAuMjUgcGVyIHNxLiBmdC5cbiIsDQogIiAgOTUlIENJOiAgICBbJDE0Mi4xMCwgJDE1OC40MF1cbiIsDQogIiAgcC12YWx1ZTogICA8IDAuMDAxXG4iLA0KICJcbkludGVycHJldGF0aW9uOiBFYWNoIGFkZGl0aW9uYWwgc3F1YXJlIGZvb3QgaXMgYXNzb2NpYXRlZCB3aXRoXG4iLA0KICJhbiBlc3RpbWF0ZWQgJDE1MCBpbmNyZWFzZSBpbiBwcmljZSwgYW5kIHdlIGFyZSA5NSUgY29uZmlkZW50XG4iLA0KICJ0aGUgdHJ1ZSBpbmNyZWFzZSBpcyBiZXR3ZWVuICQxNDIgYW5kICQxNTguXG4iKQ0KYGBgDQoNCjIuICAqKlB1YmxpYyBIZWFsdGg6KiogQSBsb2dpc3RpYyByZWdyZXNzaW9uIHN0dWRpZXMgcmlzayBmYWN0b3JzIGZvciBhIGRpc2Vhc2UuIFRoZSAqKmluZmVyZW5jZSBvbiB0aGUgb2RkcyByYXRpbyBmb3Igc21va2luZyoqIChlLmcuLCBPUiA9IDIuNSB3aXRoIENJIFsyLjEsIDMuMF0pIGFsbG93cyB1cyB0byBzdGF0ZTogU21va2luZyBpcyBhc3NvY2lhdGVkIHdpdGggMi41IHRpbWVzIHRoZSBvZGRzIG9mIGRpc2Vhc2UsIGFuZCB3ZSBhcmUgY29uZmlkZW50IHRoZSB0cnVlIGluY3JlYXNlIGlzIGF0IGxlYXN0IDIuMS1mb2xkLg0KDQoNCiMjIEJheWVzaWFuIEluZmVyZW5jZSAoVGhlIENvaGVyZW50IFVwZGF0ZSkNCg0KKiAqKldoYXQgaXQgaXM6KiogQSBwYXJhZGlnbSB0aGF0ICoqY29tYmluZXMgcHJpb3Iga25vd2xlZGdlL2JlbGllZioqIChwcmlvciBkaXN0cmlidXRpb24pIHdpdGggKipvYnNlcnZlZCBkYXRhKiogKGxpa2VsaWhvb2QpIHRvIGZvcm0gYW4gdXBkYXRlZCAqKnBvc3RlcmlvciBkaXN0cmlidXRpb24qKiBmb3IgYSBwYXJhbWV0ZXIuDQoNCiogKipCaWctUGljdHVyZSBNaW5kc2V0OioqIFlvdSB0cmVhdCBwYXJhbWV0ZXJzIGFzIHByb2JhYmlsaXN0aWMgZW50aXRpZXMuIFlvdSBzdGFydCB3aXRoIGEgcHJpb3IgKHdoaWNoIGNhbiBiZSBvYmplY3RpdmUgb3Igc3ViamVjdGl2ZSksIG9ic2VydmUgZGF0YSwgYW5kIHJhdGlvbmFsbHkgdXBkYXRlIHlvdXIgYmVsaWVmcy4gVGhlIHJlc3VsdCBpcyBhIGZ1bGwgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIGZvciB0aGUgcGFyYW1ldGVyLg0KDQpgYGB7ciBiYXllc2lhbi11cGRhdGUsIGZpZy5jYXA9IkJheWVzaWFuIEluZmVyZW5jZTogVXBkYXRpbmcgUHJpb3IgQmVsaWVmIHdpdGggRGF0YSIsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTV9DQojIFNpbXVsYXRlIEJheWVzaWFuIHVwZGF0aW5nDQpzZXQuc2VlZCg3ODkpDQp4IDwtIHNlcSgwLCAxLCBsZW5ndGgub3V0ID0gMTAwKQ0KDQojIFByaW9yIChtb2RlcmF0ZWx5IGluZm9ybWVkKQ0KcHJpb3IgPC0gZGJldGEoeCwgOCwgOCkNCg0KIyBMaWtlbGlob29kIChkYXRhOiAxNSBzdWNjZXNzZXMgb3V0IG9mIDIwIHRyaWFscykNCmEgPC0gMTUNCmIgPC0gNQ0KbGlrZWxpaG9vZCA8LSBkYmV0YSh4LCBhLCBiKQ0KDQojIFBvc3Rlcmlvcg0KcG9zdGVyaW9yIDwtIGRiZXRhKHgsIDggKyBhLCA4ICsgYikNCg0KIyBQbG90DQpwbG90X2RmIDwtIGRhdGEuZnJhbWUoDQogIHggPSByZXAoeCwgMyksDQogIGRlbnNpdHkgPSBjKHByaW9yLCBsaWtlbGlob29kLCBwb3N0ZXJpb3IpLA0KICBkaXN0cmlidXRpb24gPSByZXAoYygiUHJpb3IiLCAiTGlrZWxpaG9vZCAoRGF0YSkiLCAiUG9zdGVyaW9yIiksIGVhY2ggPSBsZW5ndGgoeCkpDQopDQoNCmJheWVzIDwtIGdncGxvdChwbG90X2RmLCBhZXMoeCA9IHgsIHkgPSBkZW5zaXR5LCBjb2xvciA9IGRpc3RyaWJ1dGlvbiwgbGluZXR5cGUgPSBkaXN0cmlidXRpb24pKSArDQogIGdlb21fbGluZShzaXplID0gMS4yKSArDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJQcmlvciIgPSAiYmx1ZSIsICJMaWtlbGlob29kIChEYXRhKSIgPSAic3RlZWxibHVlIiwgIlBvc3RlcmlvciIgPSAicmVkIikpICsNCiAgc2NhbGVfbGluZXR5cGVfbWFudWFsKHZhbHVlcyA9IGMoIlByaW9yIiA9ICJzb2xpZCIsICJMaWtlbGlob29kIChEYXRhKSIgPSAic29saWQiLCAiUG9zdGVyaW9yIiA9ICJzb2xpZCIpKSArDQogIGxhYnMoeCA9ICJQYXJhbWV0ZXIgKGUuZy4sIHN1Y2Nlc3MgcHJvYmFiaWxpdHkpIiwgeSA9ICJEZW5zaXR5IiwNCiAgICAgICAjdGl0bGUgPSAiQmF5ZXNpYW4gVXBkYXRpbmc6IFByaW9yIOKGkiBMaWtlbGlob29kIOKGkiBQb3N0ZXJpb3IiLA0KICAgICAgIGNvbG9yID0gIkRpc3RyaWJ1dGlvbiIsIGxpbmV0eXBlID0gIkRpc3RyaWJ1dGlvbiIpICsNCiAgdGhlbWUoDQogIHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSA0MCwgciA9IDIwLCBiID0gMjAsIGwgPSAyMCwgdW5pdCA9ICJwdCIpLA0KICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dCgNCiAgICBtYXJnaW4gPSBtYXJnaW4odCA9IDIwLCBiID0gMCkpLCAgIyBUb3AgYW5kIGJvdHRvbSBtYXJnaW5zDQogIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4odCA9IDEwKSksDQogIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChtYXJnaW4gPSBtYXJnaW4ociA9IDEwKSkpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpnZ3Bsb3RseShiYXllcykNCmBgYA0KDQojIyMgKipVc2UtQ2FzZSBFeGFtcGxlczoqKg0KDQoxLiAgKipEcnVnIERldmVsb3BtZW50OioqIEVhcmx5IHRyaWFscyBwcm92aWRlIGEgKipwcmlvcioqIG9uIGEgZHJ1ZydzIGVmZmljYWN5LiBBIGxhcmdlciBQaGFzZSAzIHRyaWFsIHByb3ZpZGVzICoqZGF0YSoqLiAqKkJheWVzaWFuIGluZmVyZW5jZSoqIGNvbWJpbmVzIHRoZW0gdG8gcHJvZHVjZSBhICoqcG9zdGVyaW9yIHByb2JhYmlsaXR5KiogdGhhdCB0aGUgZHJ1ZyBleGNlZWRzIGEgbWluaW11bSBlZmZlY3RpdmVuZXNzIHRocmVzaG9sZOKAlGEgZGlyZWN0LCBpbnR1aXRpdmUgc3RhdGVtZW50IGZvciBkZWNpc2lvbi1tYWtlcnMuDQoNCg0KMi4gICoqTWFjaGluZSBMZWFybmluZy9TcGFtIEZpbHRlcmluZzoqKiBUaGUgZmlsdGVyIGhhcyBhICoqcHJpb3IgYmVsaWVmKiogYWJvdXQgdGhlIHByb2JhYmlsaXR5IGFuIGVtYWlsIGlzIHNwYW0uIEl0IHVwZGF0ZXMgdGhpcyBiZWxpZWYgYmFzZWQgb24gdGhlICoqZGF0YSoqIChwcmVzZW5jZSBvZiBrZXl3b3JkcyBsaWtlICJmcmVlLCIgIndpbm5lciIpLiBUaGUgKipwb3N0ZXJpb3IgcHJvYmFiaWxpdHkqKiBkaWN0YXRlcyB0aGUgInNwYW0vbm90IHNwYW0iIGNsYXNzaWZpY2F0aW9uLg0KDQoNCg0KIyBTeW50aGVzaXMgJiBDYXV0aW9ucw0KDQojIyBLZXkgUmVsYXRpb25zaGlwcyBhbmQgQ29tcGFyaXNvbnMNCg0KYGBge3IgY29tcGFyaXNvbi10YWJsZSwgZWNobz1GQUxTRX0NCiMgQ3JlYXRlIGEgY29tcGFyaXNvbiB0YWJsZQ0KY29tcGFyaXNvbl9kZiA8LSBkYXRhLmZyYW1lKA0KICBNZXRob2QgPSBjKCJDb25maWRlbmNlIEludGVydmFscyIsICJIeXBvdGhlc2lzIFRlc3RzIiwgIlJlZ3Jlc3Npb24gSW5mZXJlbmNlIiwgIkJheWVzaWFuIEluZmVyZW5jZSIpLA0KICBRdWVzdGlvbiA9IGMoIldoYXQgaXMgdGhlIHBsYXVzaWJsZSByYW5nZT8iLCAiSXMgdGhlcmUgZXZpZGVuY2UgYWdhaW5zdCBI4oKAPyIsICJXaGF0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB2YXJpYWJsZXM/IiwgIldoYXQgc2hvdWxkIHdlIGJlbGlldmUgZ2l2ZW4gZGF0YSBhbmQgcHJpb3I/IiksDQogIE91dHB1dCA9IGMoIkludGVydmFsIGVzdGltYXRlIiwgInAtdmFsdWUsIGRlY2lzaW9uIiwgIlBhcmFtZXRlciBlc3RpbWF0ZXMgd2l0aCBDSXMiLCAiUG9zdGVyaW9yIGRpc3RyaWJ1dGlvbiIpLA0KICBJbnRlcnByZXRhdGlvbiA9IGMoIkxvbmctcnVuIGZyZXF1ZW5jeSBvZiBjb3ZlcmFnZSIsICJQcm9iYWJpbGl0eSBvZiBkYXRhIGlmIEjigoAgdHJ1ZSIsICJFZmZlY3Qgc2l6ZSB3aXRoIHVuY2VydGFpbnR5IiwgIkRlZ3JlZSBvZiBiZWxpZWYgaW4gcGFyYW1ldGVyIHZhbHVlcyIpDQopDQoNCmtuaXRyOjprYWJsZShjb21wYXJpc29uX2RmLCANCiAgICAgICAgICAgICBjYXB0aW9uID0gIkNvbXBhcmlzb24gb2YgU3RhdGlzdGljYWwgSW5mZXJlbmNlIE1ldGhvZHMiLA0KICAgICAgICAgICAgIGNvbC5uYW1lcyA9IGMoIk1ldGhvZCIsICJQcmltYXJ5IFF1ZXN0aW9uIiwgIk1haW4gT3V0cHV0IiwgIkludGVycHJldGF0aW9uIikpDQpgYGANCg0KKiAqKkVzdGltYXRpb24gKENJKSBhbmQgVGVzdGluZyAocC12YWx1ZXMpIGFyZSBsaW5rZWQ6KiogQSA5NSUgQ0kgdGhhdCAqKmV4Y2x1ZGVzKiogYSBudWxsIHZhbHVlIChsaWtlIDApIGNvcnJlc3BvbmRzIHRvIGEgaHlwb3RoZXNpcyB0ZXN0IHJlamVjdGluZyBI4oKAIGF0IM6xPTAuMDUuDQoNCmBgYHtyIGNpLXRlc3QtcmVsYXRpb25zaGlwLCBlY2hvPVRSVUUsIGV2YWw9VFJVRX0NCiMgRGVtb25zdHJhdGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ0kgYW5kIGh5cG90aGVzaXMgdGVzdA0KDQoNCiMgU2ltdWxhdGUgZGF0YSB3aGVyZSBDSSBleGNsdWRlcyAwDQpzZXQuc2VlZCgzMjEpDQpzYW1wbGVfZGF0YSA8LSBybm9ybSg1MCwgbWVhbiA9IDEuNSwgc2QgPSAyKQ0KDQojIFQtdGVzdA0KdGVzdF9yZXN1bHQgPC0gdC50ZXN0KHNhbXBsZV9kYXRhLCBtdSA9IDApDQpjaSA8LSB0ZXN0X3Jlc3VsdCRjb25mLmludA0KDQpjYXQoIiAgRGVtb25zdHJhdGlvbjogUmVsYXRpb25zaGlwIGJldHdlZW4gQ0kgYW5kIEh5cG90aGVzaXMgVGVzdFxuIiwNCiI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iLA0Kc3ByaW50ZigiXG4gIFNhbXBsZSBtZWFuOiAlLjNmXG4iLCBtZWFuKHNhbXBsZV9kYXRhKSksDQpzcHJpbnRmKCI5NSUlIENvbmZpZGVuY2UgSW50ZXJ2YWw6IFslLjNmLCAlLjNmXVxuIiwgY2lbMV0sIGNpWzJdKSwNCnNwcmludGYoInAtdmFsdWUgZm9yIEjigoA6IM68ID0gMDogJS40ZlxuIiwgdGVzdF9yZXN1bHQkcC52YWx1ZSksDQpzcHJpbnRmKCJcbiB3ZSAlcyB0aGUgbnVsbCBoeXBvdGhlc2lzIGF0IM6xPTAuMDUuXG4iLCANCiAgICAgICAgICAgIGlmZWxzZSh0ZXN0X3Jlc3VsdCRwLnZhbHVlIDwgMC4wNSwgIlJFSkVDVCIsICJGQUlMIFRPIFJFSkVDVCIpKSkNCmBgYA0KDQoNCiogKipTdGF0aXN0aWNhbCB2cy4gUHJhY3RpY2FsIFNpZ25pZmljYW5jZToqKiBBIHRlc3QgY2FuIGZpbmQgYSB0aW55LCAqKnN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQqKiBlZmZlY3QgKGR1ZSB0byBodWdlIHNhbXBsZSBzaXplKSwgYnV0IGl0IG1heSBiZSAqKnByYWN0aWNhbGx5IG1lYW5pbmdsZXNzKiouICoqQWx3YXlzIGxvb2sgYXQgdGhlIGVzdGltYXRlZCBlZmZlY3Qgc2l6ZSBhbmQgaXRzIENJLioqDQoNCiogKipJbmZlcmVuY2UgUmVxdWlyZXMgUmVwcmVzZW50YXRpdmUgRGF0YToqKiBHYXJiYWdlIGluLCBnYXJiYWdlIG91dC4gQmlhc2VkIHNhbXBsaW5nIGludmFsaWRhdGVzIGFueSBpbmZlcmVuY2UsIG5vIG1hdHRlciBob3cgc29waGlzdGljYXRlZC4NCg0KKiAqKkZyZXF1ZW50aXN0IChDSS9UZXN0cykgdnMuIEJheWVzaWFuIE1pbmRzZXQ6KiogIA0KICAqICoqRnJlcXVlbnRpc3Q6KiogUHJvYmFiaWxpdHkgPSBsb25nLXJ1biBmcmVxdWVuY3kuIFBhcmFtZXRlcnMgYXJlIGZpeGVkLCBkYXRhIGlzIHJhbmRvbS4gIA0KICAqICoqQmF5ZXNpYW46KiogUHJvYmFiaWxpdHkgPSBkZWdyZWUgb2YgYmVsaWVmLiBQYXJhbWV0ZXJzIGFyZSByYW5kb20sIGRhdGEgaXMgZml4ZWQuICANCiAgQm90aCBhcmUgcG93ZXJmdWwgdG9vbHM7IHRoZSBjaG9pY2Ugb2Z0ZW4gZGVwZW5kcyBvbiB0aGUgcXVlc3Rpb24sIGZpZWxkLCBhbmQgYXZhaWxhYmlsaXR5IG9mIHByaW9yIGluZm9ybWF0aW9uLg0KDQoNCiMgIEtleSBUYWtlYXdheQ0KDQpTdGF0aXN0aWNhbCBpbmZlcmVuY2UgaXMgdGhlICoqc2NpZW5jZSBvZiBkaXNjaXBsaW5lZCBsZWFybmluZyBmcm9tIGRhdGEgaW4gdGhlIGZhY2Ugb2YgdW5jZXJ0YWludHkuKiogSXQgbW92ZXMgdXMgZnJvbSBzaW1wbHkgZGVzY3JpYmluZyBvdXIgc2FtcGxlICgiVGhlIGF2ZXJhZ2UgaW4gb3VyIGRhdGEgd2FzIDEwIikgdG8gbWFraW5nICoqZ2VuZXJhbGl6YWJsZSBzdGF0ZW1lbnRzIHdpdGggcXVhbnRpZmllZCB1bmNlcnRhaW50eSoqICgiV2UgYXJlIDk1JSBjb25maWRlbnQgdGhlIHBvcHVsYXRpb24gYXZlcmFnZSBpcyBiZXR3ZWVuIDkgYW5kIDExIikuIA0KDQpNYXN0ZXJpbmcgdGhlIGJpZyBwaWN0dXJlIGFsbG93cyB5b3UgdG8gY2hvb3NlIHRoZSByaWdodCB0b29sIGZvciB0aGUgcXVlc3Rpb24gYXQgaGFuZCwgZnJvbSBlc3RpbWF0aW5nIGEgbWFya2V0IHNpemUsIHRvIHRlc3RpbmcgYSBuZXcgbWVkaWNhbCB0cmVhdG1lbnQsIHRvIHVwZGF0aW5nIGEgcmVjb21tZW5kYXRpb24gYWxnb3JpdGhtLg0KDQpgYGB7ciBmaW5hbC1zdW1tYXJ5LCBlY2hvPUZBTFNFLCBmaWcuY2FwPSJUaGUgSW5mZXJlbmNlIFByb2Nlc3M6IEZyb20gRGF0YSB0byBLbm93bGVkZ2UiLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQ0KIyBGaW5hbCBzdW1tYXJ5IHZpc3VhbGl6YXRpb24NCnByb2Nlc3Nfc3RlcHMgPC0gZGF0YS5mcmFtZSgNCiAgc3RlcCA9IDE6NSwNCiAgbGFiZWwgPSBjKCJEYXRhXG5Db2xsZWN0aW9uIiwgIk1vZGVsXG5TcGVjaWZpY2F0aW9uIiwgIkluZmVyZW5jZVxuUHJvY2VkdXJlIiwgIlVuY2VydGFpbnR5XG5RdWFudGlmaWNhdGlvbiIsICJLbm93bGVkZ2UgJlxuRGVjaXNpb24iKSwNCiAgeCA9IDE6NSwNCiAgeSA9IGMoMCwgMSwgMCwgMSwgMCkNCikNCg0KZ2dwbG90KHByb2Nlc3Nfc3RlcHMsIGFlcyh4ID0geCwgeSA9IHkpKSArDQogIGdlb21fcGF0aChjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDEpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMzAsIGNvbG9yID0gIiMyYzNlNTAiLCBhbHBoYSA9IDAuOCkgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbGFiZWwpLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSAzKSArDQogIGdlb21fdGV4dCh4ID0gMywgeSA9IDEuNSwgbGFiZWwgPSAiVGhlIFN0YXRpc3RpY2FsIEluZmVyZW5jZSBQcm9jZXNzIiwgDQogICAgICAgICAgICBzaXplID0gNSwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgeGxpbSgwLjUsIDUuNSkgKw0KICB5bGltKC0wLjUsIDEuOCkgKw0KICB0aGVtZV92b2lkKCkgKw0KICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLCAxLCAxLCAxKSwgImNtIikpDQpgYGANCg0KDQojIEZ1cnRoZXIgUmVzb3VyY2VzDQoNCiogKipSIFBhY2thZ2VzIGZvciBJbmZlcmVuY2U6KioNCiAgLSBCYXNpYzogYHN0YXRzYCAoYmFzZSBSKSwgYGluZmVyYCAodGlkeXZlcnNlIGFwcHJvYWNoKQ0KICAtIEJheWVzaWFuOiBgcnN0YW5gLCBgYnJtc2AsIGByc3RhbmFybWANCiAgLSBTcGVjaWFsaXplZDogYHN1cnZpdmFsYCwgYGxtZTRgLCBgbWdjdmANCg0KKiAqKlByYWN0aWNlIHdpdGg6KiogYGluZmVyOjpnZW5lcmF0ZSgpYCwgYGluZmVyOjpjYWxjdWxhdGUoKWAgZm9yIHNpbXVsYXRpb24tYmFzZWQgaW5mZXJlbmNlDQoNCiogKipOZXh0IFN0ZXBzOioqIEV4cGVyaW1lbnRhbCBkZXNpZ24sIHBvd2VyIGFuYWx5c2lzLCBtdWx0aXBsZSB0ZXN0aW5nIGNvcnJlY3Rpb25zLCBjYXVzYWwgaW5mZXJlbmNlIGZyYW1ld29ya3MuDQoNCioqUmVtZW1iZXI6KiogVGhlIG1hcCBpcyBub3QgdGhlIHRlcnJpdG9yeS4gU3RhdGlzdGljYWwgbW9kZWxzIGFyZSBzaW1wbGlmaWVkIHJlcHJlc2VudGF0aW9ucyBvZiByZWFsaXR54oCUcG93ZXJmdWwsIGJ1dCBhbHdheXMgaW1wZXJmZWN0Lg0K